 
  

 






<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html>

<!-- Mirrored from www.javapractices.com/topic/TopicAction.do?Id=241 by HTTrack Website Copier/3.x [XR&CO'2010], Sun, 12 Jun 2011 17:28:08 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=UTF-8"><!-- /Added by HTTrack -->
<head>
 <title>
  Java Practices -> Use CVS or other source code control
 </title>
 <link rel="stylesheet" type="text/css" href="../stylesheet8.css" media="all">
 
 <link rel="shortcut icon" href='../images/favicon.ico' type="image/vnd.microsoft.icon">
 <meta name="description" content="Concise presentations of java programming practices, tasks, and conventions, amply illustrated with syntax highlighted code examples.">
 
 <meta name='keywords' content='java,java programming,java practices,java idiom,java style,java design patterns,java coding conventions,'>
 
 
</head>
 
<body>


<div class='menu-bar'>
 
  <a href='../home/HomeAction.html' title='Table of Contents'>Home</a> |
  <a href='../vote/VoteSummaryAction-2.html' title='View Poll Results'>Poll</a> |
   
  <A href='../feedback/FeedbackAction451f-2.html?Operation=Show' title='Send Your Feedback'>Wiki</a> |
  <b><a href='../source/SourceAction-2.html' title='Grab Source Code'>Source Code</a></b><IMG class='no-margin' SRC="../images/goldstar.gif" ALT=""> |

  <a href='http://www.web4j.com/Java_Web_Application_Framework_Overview.jsp?From=1' title='Free Download - Java Web Application Framework'><b>WEB4J</b></a> |
  
  <a href='http://www.date4j.net/' title='Replacement for java.util.Date'><b>DATE4J</b></a> |

   <a href='../references/ReferencesAction-2.html' title='References'>Links</a>
   
  <form action='http://www.javapractices.com/search/SearchAction.do' method='get' class='search-form'>
   <input type='text' name='SearchTerms' value="" size=12 maxlength=50 class='search'>
   <input type='submit' value="Search">
  </form>
 
</div>

<P>



  

 






<p class="display-messages">

 

 

</p>


<div class="main-layout">
 
   

 




<div class='page-title'>Use CVS or other source code control</div>

<div class='main-body'>
 
<br>Using source code control is strongly recommended for all non-trivial projects. 
For projects with multiple developers, source code control is almost a necessity.
The advantages of source code control are :

<ul>
 <li>it acts as the definitive version of the source.
 <li>it allows for automated daily backups.
 <li>it allows <i>time travel</i>, in the sense of letting you create a snapshot of the code as it appeared at some specific time in the past.
 <li>it lets you create <i>parallel universes</i>, by letting you define <i>branches</i> for your project. 
  The most common case of this is having a bug-fix branch along side a main trunk.
</ul>

<P>There are many source code control systems available. 
<a href='http://en.wikipedia.org/wiki/Concurrent_Versions_System'>CVS</a> (Concurrent Version System) is one such tool, and it's widely used.
As an aid to those who already use CVS, the following is a list of reminders for its typical use. 
For a more complete introduction to CVS, an excellent reference is <i>Pragmatic Version Control Using CVS</i> by Thomas and Hunt.

<h3>CVS Terminology</h3>
<ul>
 <li><i>repository</i> - where CVS stores the source code for projects.
 <li><i>CVSROOT</i> - an environment variable which points to the repository.
 <li><i>workspace</i> or <i>working directory</i> - where the developer does their work. 
  A private copy of the code, on the developer's host.
 <li><i>checkout</i> - the initial fetch of a project's source tree from the repository.
 <li><i>update</i> - a re-fetch of a file or set of files <i>after</i> the initial checkout.
 <li><i>commit</i> - after verifying edits are correct, the developer will use a <tt>commit</tt> to post their edits from their workspace back to the repository.
 <li><i>revision</i> - version of a file, denoted by a string of numbers, as in 1.2 (on the trunk) or 1.1.2.3 (on a branch).
 <li><i>trunk</i> or <i>mainline</i> - the main branch of development. Releases are often branched off the trunk.
 <li><i>dead files</i> - files that are removed from the project aren't really removed. Instead, they are moved into the 'dead' state.
 <li><i>regular tag</i> - label for a particular set of revisions in the project. 
  Allows you to define specific snapshots of the project, which can be used later to recreate that snapshot. 
  Tags always start with a letter, so you can always distinguish them from revisions (which are numeric, as in 1.2 or 1.1.2.3). 
 <li><i>branch tag</i> - label for a project branch. Always starts with a letter. Branches allow parallel development.
 <li><i>HEAD</i> - a reserved tag name, refers to the most recent revision in the repository.
 <li><i>BASE</i> - a reserved tag name, refers to the revision checked out into the workspace. If a developer has modified a file, then the BASE is no longer the same as the workspace copy.
 <li><i>sticky</i> - many CVS commands are sticky. 
 This means that the command is implicitly applied using the most recent tag that was specified (either regular tag or branch tag).
 Thus, you can specify a tag once, and then subsequent commands will assume that tag also applies as the default. 
 The idea is to let you work without repeatedly specifying the tag over and over again.
</ul>

<h3>CVS Edit Codes</h3>
<ul>
 <li>? - an item in the local workspace has not yet been added to the repository
 <li>U - updated (either changed or added new)
 <li>P - updated via a 'patch' (more or less the same as U)
 <li>M - item in the local workspace has been modified after retrieval from the repository
 <li>C - conflicting edits found between two revisions. 
  Such conflicts need manual intervention, since they cannot be automatically merged together.
 <li>A - added to CVS, but not yet committed.
 <li>R - removed from CVS, but not yet committed.
</ul>

<h3>Getting Started With CVS</h3>
<ul> 
 <li>to use CVS from the command line, add CVS to your PATH environment variable.
 <li>by default, most commands apply recursively to all subdirectories.
 <li>CVS usually outputs dates and times using Universal Time, but you can often alter the output time zone, using the '-z' option.
 <li>CVS lets you define a simple local repository on your host's file system (see below). When getting 
  started with CVS, it's highly recommended that you create such a 'sandbox' repository, as a safe place to experiment with CVS.
</ul>

<P><i>cvs --help-commands</i><br>
Lists all CVS commands.

<P><i>cvs -H update</i><br>
Displays help for the update command.
 
<P><i>cvs -d C:\sandbox init</i><br>
Creates a local 'sandbox' repository, on the local file system. 
<i>Such a sandbox is very helpful for experimenting with CVS.</i>
This is a nice feature, since you don't have to set up a server in order to create the repository. 
For more formal development, however, your 'real' source code will be stored in a server on another host, not on the local file system.

<P><i>tmp>set CVSROOT=C:\sandbox</i><br>
<i>tmp>cvs import -m "Play around with CVS" myproject myproject initial</i><br>
Create a new project named 'myproject', built from the current contents of your tmp directory (and subdirectories), and place the new project into your sandbox repository.


<P><i>work>cvs -d C:\sandbox checkout myproject</i><br>
Retrieves from the sandbox repository a copy of all files in myproject, and places them into work/myproject. Retrieves the latest version of each file (the HEAD).


<h3>Common Commands</h3>
<i>cvs status Blah.java</i><br>
Lists general information about the file, whether it has been edited, it's revision, and what branch it's on.


<P><i>cvs status -q Blah.java</i><br>
More concise status listing.


<P><i>cvs -q update -P -d</i><br>
Updates your workspace with the latest repository files. 
Performs a merge. Most merges will succeed, but some will fail, and will result in a conflict.
Conflicts must be handled manually.

<P>This is a 'sticky' operation (see above). 
If your workspace is on the trunk, then you are updated with new trunk files. 
If your workspace is on a branch, then you are updated with files from that branch.

<P><i>cvs -nq update -P -d</i><br>
Compares your workspace with the repository <i>without</i> actually doing the update.
Does not write to your workspace.
The '-n' option means "don't really do this, just show me the current differences between my workspace and the HEAD of the repository."


<P><i>cvs -q update -P -d -A</i><br>
Updates your workspace, and ensures you're updated with the trunk, not a branch.

<P><i>cvs -q udpate -P -d -r REL_1_0</i><br>
Updates your workspace with a specific release branch.

<P><i>cvs commit -m "Some appropriate description"</i><br>
Commits all edits to all files in and under the current directory.


<P><i>cvs history -c -u myuserid -D yesterday -z AST</i><br>
Displays what a specific user id committed yesterday, and displays the result in a specific time zone (AST) instead of Universal Time.


<h3>Occasional Commands</h3>
<i>work>cvs checkout myproject</i><br>
Fetches an entire project from the repository, and places it in the local directory named work/myproject.

<P><i>cvs add Blah.java</i><br>
<i>cvs commit -m "My new file." Blah.java</i><br>
Adds a new file to the repository. 
Note that you need to commit the file before the addition is complete.

<P><i>cvs add -kb jstl.jar</i><br>
<i>cvs commit -m "Required library." jstl.jar</i><br>
Adds a new binary file to the repository.
Again, you need to commit the file before the addition is complete.


<P><i>work>del Blah.java</i><br>
<i>work>cvs remove Blah.java</i><br>
<i>work>cvs commit "No longer needed." Blah.java</i><br>
Deletes a file. This has 3 steps.


<P><i>cvs history -c -D "2010/01/01" -z AST Blah.java</i><br>
Displays a history of commits on a given file, after a given date, with date-time output in a specific time zone (AST). 

<P><i>cvs log -d today Blah.java</i><br>
Shows messages for all commits done today for a given file.

<P><i>cvs -q log -wmyuserid -d"2010/04/13 13:00:00" -S</i><br>
Shows messages for all commits done by a certain user, after a given date-time

<P><i>cvs log -rREL_1_0 -wmyuserid Blah.java</i><br>
Shows the commit messages for a given user id, performed on a specific branch.

<P><i>work>rename SolarSys.java SolarSystem.java</i><br>
<i>work>cvs remove SolarSys.java</i><br>
<i>work>cvs add SolarSystem.java</i><br>
<i>work>cvs commit -m "Better name." SolarSystem.java</i><br>
Renames a file. This has 4 steps.

<P><i>cvs rtag -b RB_1_0 myproject</i><br>
Creates a release branch named 'RB_1_0' for a project named 'myproject'.
<i>This command is applied to the repository, not to the workspace.</i>
A release branch can be created before the release, if desired.
Then, each release candidate is built using the head of the release branch.
When the release is final, then you apply a regular tag to the release branch, to mark the exact point of release.

<P><i>cvs tag REL_1_0</i><br>
Tags the repository files in your BASE -- the <i>unmodified</i> revisions checked out to your local workspace.

<P><i>cvs diff --side-by-side Blah.java</i><br>
Shows the differences between your workspace and the BASE.


<h3>CVS Quirks</h3>
<ul>
 <li>after you have initially checked out a project to a given local workspace, CVS will remember both the location of the repository, <i>and</i> your login credentials (as long as you don't log out). 
  Thus, there's no need to repeatedly state the location of the repository when issuing CVS commands.
 <li>if you try to commit a file which actually has no differences with the repository file, CVS will not create a new revision.
</ul>



<h3>Merging From Branch To Trunk</h3>
There are two ways to merge from a branch into the trunk. 

<P><i>cvs -q update -j 1.1.2.2 -j 1.1.2.3 Blah.java</i><br>
This is usually the preferred method. 
Note the presence of 2 '-j' options. 
This means that <i>only the edits that took the file from 1.1.2.2 to 1.1.2.3 are to be merged into the trunk</i>.
This is very helpful, because it can avoid the repetition of possible conflicts that may have already occurred during previous merges.



<P><i>cvs -q update -j 1.1.2.3 Blah.java</i><br>
This is usually not the preferred style (see above). 
This merge has a single '-j' option. 
The implementation of this merge will need to go back to the common ancestor of the trunk and the branch. 
The problem with this style is how conflicts are treated. 
If such a merge has a conflict, it can certainly be resolved, just like any other conflict. 
However, the <i>conflict will resurface again later</i> should you need to perform another merge between the branch and the trunk.


<h3>Separate Workspaces For Each Branch</h3>
Although there are many variations, it's typical to be working on 2 code streams (sometimes more) :
<ul>
 <li>the trunk : main development for the next release
 <li>a branch : bug fixes for the most recent release, already in production
</ul>
 
<P>
When working on more than a single branch, it's helpful to be able to switch rapidly between them.
It's certainly possible to use a single local workspace to do so, using a <tt>'cvs update'</tt> command which specifies the appropriate branch.

<P>However, many find it simpler and more convenient to just use a separate workspace for each branch.
Since the <tt>update</tt> command is "sticky", and remembers the branch from which a workspace originally came from, there's usually no asymmetry between working on the branch and working on the trunk. 


<br>
<br>

</div>





<div class='topic-section'>Would you use this technique?</div>
<div class='main-body'>
  
  <form action="http://www.javapractices.com/vote/AddVoteAction.do" method='post'>
    Yes<input type='radio' name='Choice' value='Y' >
    &nbsp;&nbsp;No<input type='radio' name='Choice' value='N'>
    &nbsp;&nbsp;Undecided<input type='radio' name='Choice' value="?" >
    &nbsp;&nbsp;<input type=submit value="Vote" >
    <input type='hidden' name='Operation' value='Apply'>
    <input type='hidden' name='TopicId' value='241'>
  </form>
</div>

<div style='height:10.0em;'></div>

 
 
</div>

  

 





<div align='center' class='legalese'>  
&copy; 2011 Hirondelle Systems |
<a href='../source/SourceAction-2.html'><b>Source Code</b></a><IMG class='no-margin' SRC="../images/goldstar.gif" ALT=""> |
<a href="mailto:webmaster@javapractices.com">Contact</a> |
<a href="http://creativecommons.org/licenses/by-nc-sa/1.0/">License</a> |
<a href='../apps/cjp.rss'>RSS</a>
<!-- ukey="2AC36CD2" -->
<!-- ckey="16DF3D87" -->
<br>

 Individual code snippets can be used under this <a href='../LICENSE.txt'>BSD license</a> - Last updated on June 6, 2010.<br>
 Over 150,000 unique IPs last month - <span title='Java Practices 2.6.5, Mon May 16 00:00:00 EDT 2011'>Built with</span> <a href='http://www.web4j.com/'>WEB4J</a>.<br>
 - In Memoriam : Bill Dirani -
</div>

<script src="../../www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-2633428-1";
urchinTracker();
</script>



</body>

<!-- Mirrored from www.javapractices.com/topic/TopicAction.do?Id=241 by HTTrack Website Copier/3.x [XR&CO'2010], Sun, 12 Jun 2011 17:28:08 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=UTF-8"><!-- /Added by HTTrack -->
</html>
